# coding=utf-8
import copy
import inspect
import os
import sys
import time
import types

from base import sg
import keyboard

def init():
	import setting
	if setting.HOT_RELOAD:
		RoloadMgr.ins.init()


@sg.singleton
class RoloadMgr(sg.SingletonBase["RoloadMgr"]):
	def __init__(self):
		self.m_fTime = None
	
	def init(self):
		keyboard.add_hotkey('ctrl+s', self.reload)
		self.m_fTime = time.time()
	
	def reload(self):
		dData = sys.modules
		for key in dData:
			oModule = dData[key]
			try:
				sPath = oModule.__file__
				fTime = os.path.getmtime(sPath)
				if fTime <= self.m_fTime:
					continue
				self.reload_module(oModule, sPath)
			except:
				pass
	
	def reload_module(self, oModule, sPath):
		with open(sPath, 'r', encoding='utf-8') as file:
			sData = str(file.read())
		dOldData = dict(oModule.__dict__)
		dNewData = copy.copy(dOldData)
		
		exec(sData, dNewData)
		self.reload_func(oModule, dOldData, dNewData)
		self.m_fTime = time.time()
		print("重载成功:" + sPath)
	
	def reload_func(self, obj, dOldData, dNewData):
		for key in dNewData:
			if key.startswith("__"):
				continue
			value = dNewData[key]
			if isinstance(value, types.FunctionType) or isinstance(value, types.MethodType) \
					or isinstance(value, str) or isinstance(value, dict) or isinstance(value, dict):  # 直接覆盖
				setattr(obj, key, dNewData[key])
			elif inspect.isclass(value):
				if key in dOldData:
					oldCls = dOldData[key]
					self.reload_func(oldCls, dict(oldCls.__dict__), dict(value.__dict__))
				else:
					setattr(obj, key, dNewData[key])
			elif inspect.ismodule(value):
				pass
	
		